import * as fs from "fs";
import * as path from 'path';
import * as uglify from 'uglify-es';
import { createDirSync, hashFile } from '../utils/FileUtil';

/**
 * 解析index.js文件, 将index.js中的注释删掉, 并得到需要合并的js文件列表 这里解析的时候是解析index.js里面的loadLib
 * @param binPath index.js的文件路径
 * @param jsName index.js的文件名, index.js
 */
export function paserIndexJs(binPath: string, jsName: string = "index.js"): { js: string[], loadJs: string[], jsReplace: string[], loadJsReplaceList: string[] } {
    let jsList: string[] = [];
    let jsReplace: string[] = [];
    let loadJsList: string[] = [];
    let loadJsReplaceList: string[] = [];
    let jsStr = '';
    let jsPath = path.join(binPath, jsName);
    jsStr = fs.readFileSync(jsPath).toString();
    // 提取需要合并的js列表
    let lineReg = new RegExp(/\((\"([^\"]*)\"([\w\+\(\)\.\s]*))\)/gm);
    let result = lineReg.exec(jsStr);
    while (result) {
        if (jsList.indexOf(result[2]) === -1) {
            let str = result[2];
            str = str.replace('"', '');
            str = str.replace('"', '');
            str = str.split("?")[0];
            if (str.indexOf('.js') > 0) {
                if (str.indexOf('http') < 0) {
                    jsList.push(str);
                    jsReplace.push(result[1]);
                } else if (str.indexOf('http') == 0) {
                    loadJsList.push(str);
                    loadJsReplaceList.push(result[1]);
                }
            }
        }
        result = lineReg.exec(jsStr);
    }
    console.log(jsList);

    return {
        js: jsList,
        loadJs: loadJsList,
        jsReplace: jsReplace,
        loadJsReplaceList: loadJsReplaceList
    };
}

/**
 * 解析html文件, 将index.html中的注释删掉, 并得到需要合并的js文件列表
 * @param binPath html的文件路径
 * @param htmlName html的文件名, 默认是index.html
 */
export function paserHtml(binPath: string, htmlName: string = "index.html") {
    let jsList: string[] = [];
    let htmlStr = '';
    let htmlPath = path.join(binPath, htmlName);
    htmlStr = fs.readFileSync(htmlPath).toString();
    // 删除其中的注释
    let docReg = new RegExp(/<!--.*-->/g);
    htmlStr = htmlStr.replace(docReg, '');
    // 提取需要合并的js列表
    let jsReg = new RegExp(/src="(\S*?)js">/g);
    let result = jsReg.exec(htmlStr);

    while (result) {
        if (jsList.indexOf(result[1]) === -1) {
            jsList.push(result[1] + 'js');
        }
        result = jsReg.exec(htmlStr);
    }
    // console.log(jsList);
    let scriptReg = new RegExp(/<script[^>]*?><\/script>/g);
    htmlStr = htmlStr.replace(scriptReg, '');

    return {
        js: jsList,
        html: htmlStr
    };
}

/**
 * 保存发布web的html文件
 * @param htmlSrc 需要导出的html的内容
 * @param outputPath 导出html的路径
 * @param callback 回调函数
 * @param htmlName html的文件名
 */
export function saveWebHtml(htmlSrc: string, outputPath: string,
    callback?: () => void, htmlName: string = 'index.html') {
    let htmlPath = path.join(outputPath, htmlName);
    fs.writeFile(htmlPath, htmlSrc, (err) => {
        if (err) {
            console.warn('写入html文件失败');
            return;
        }
        console.log(`写入${htmlName}文件成功`);
        if (callback !== null) {
            callback();
        }
    });
}

/**
 * 保存zxsdk到指定目录
 * @param sdkUrl sdk的远程地址
 * @param outputPath 存放的目录
 */
export function saveZxSdk(sdkUrl: string, outputPath: string, cb?: () => void) {
    if (!sdkUrl) {
        console.log('未引用sdk');
        if (cb !== null) { cb(); }
        return;
    }
    let zxtemp = sdkUrl.split('/');
    let zxsdkName = zxtemp[zxtemp.length - 1];
    sdkUrl = sdkUrl + '?t=' + Date.now();
    var request = require('request');
    let sdkPath = path.join(outputPath, zxsdkName);
    var stream = fs.createWriteStream(sdkPath);
    request(sdkUrl).pipe(stream).on('close', () => {
        console.log('写入zxsdk文件成功');
        if (cb !== null) { cb(); }
    }).on('error', () => {
        console.warn('写入zxsdk失败');
    });
    // http.get(sdkUrl, (res) => {
    //     // console.log('res', res);
    //     res.setEncoding('utf8');
    //     let totalData = '';
    //     res.on('data', (data) => {
    //         totalData += data;
    //     }).on('end', () => {
    //         // console.log('zx sdk 加载完毕');
    //         let sdkPath = path.join(outputPath, zxsdkName);
    //         fs.writeFile(sdkPath, totalData, (err: any) => {
    //             if (err) {
    //             } else {
    //                 if (cb !== null) { cb(); }
    //             }
    //         });
    //     });
    // });
}

/** 下载保存zxsdk */
export function downloadZxSdk(htmlTxt: string, outputPath: string, cb?: () => void) {
    let zxsdkReg = new RegExp(/src="http(\S*?).js/g);
    let zxsdkResult = zxsdkReg.exec(htmlTxt);
    // console.log('zx', zxsdkResult);
    let zxurl = zxsdkResult[0].substr(5);
    saveZxSdk(zxurl, outputPath, cb);
}


export function mergeJs(jsList: string[], binPath: string, toPath: string,
    outName?: string, complete?: (codeName: string) => void, needHash: boolean = false) {

    console.log('开始合并压缩js文件列表');
    let jsTxt = '';
    for (let el of jsList) {
        let jsUri: string = el + '';
        if (jsUri.indexOf('libs/') === 0) {
            let jsLibUri = jsUri;
            if (jsLibUri.indexOf('libs/min/') < 0) {
                jsLibUri = jsLibUri.replace('libs/', 'libs/min/');
                jsLibUri = jsLibUri.replace('.js', '.min.js');
                if (fs.existsSync(path.join(binPath, jsLibUri))) {
                    jsUri = jsLibUri;
                }
            }
        }
        console.log('jsUri:', jsUri);
        let jsPath = path.join(binPath, jsUri);
        let existJs = fs.existsSync(jsPath);
        if (!existJs) {
            console.warn('没有这个js文件, 跳过', jsUri);
            continue;
        }
        let jsfile = fs.readFileSync(jsPath).toString();
        // console.log('jsfile', jsfile);
        if (jsUri.indexOf('.min.js') > 0) {
            // console.log('xxxx111')
            jsTxt += (jsfile + ';');
        } else {
            // console.log('xxxx3222')
            let rst = uglify.minify(jsfile, {
                mangle: true
            });
            jsTxt += (rst.code + ';');
        }
    }

    let outputPath = path.join(toPath, outName);
    if (needHash) {
        let buf = new Buffer(jsTxt);
        outputPath = hashFile(outputPath, buf);
    }
    fs.writeFile(outputPath, jsTxt, (err: any) => {
        console.log('写入 outputPath', outputPath);
        if (err) {
            console.warn('写入压缩文件失败');
        } else {
            console.log(`写入${outputPath}文件成功`);
            if (complete !== null) {
                complete(outputPath);
            }
        }
    });
}

export function mergeJs2(jsList: string[], binPath: string, toPath: string,
    outName?: string, complete?: (fnList?: string[]) => void, needHash: boolean = false) {

    console.log('开始合并压缩js文件列表, 分为libs.js 和 code.js');
    let libsTxt = '';
    let jsTxt = '';
    for (let el of jsList) {
        let jsUri: string = el + '';
        if (jsUri.indexOf('libs/') === 0) {
            let jsLibUri = jsUri;
            if (jsLibUri.indexOf('libs/min/') < 0) {
                jsLibUri = jsLibUri.replace('libs/', 'libs/min/');
                jsLibUri = jsLibUri.replace('.js', '.min.js');
                if (fs.existsSync(path.join(binPath, jsLibUri))) {
                    jsUri = jsLibUri;
                }
            }
        }
        console.log('jsUri:', jsUri);
        let jsPath = path.join(binPath, jsUri);
        let existJs = fs.existsSync(jsPath);
        if (!existJs) {
            console.warn('没有这个js文件, 跳过', jsUri);
            continue;
        }
        let jsfile = fs.readFileSync(jsPath).toString();
        // console.log('jsfile', jsfile);
        if (jsUri.indexOf('.min.js') > 0) {
            libsTxt += (jsfile + ';');
        } else {
            let rst = uglify.minify(jsfile, {
                mangle: true
            });
            jsTxt += (rst.code + ';');
        }
    }

    let outputPath = path.join(toPath, outName);
    let outputLibPath = path.join(toPath, 'libs.js');
    if (needHash) {
        let buf = new Buffer(jsTxt);
        outputPath = hashFile(outputPath, buf);
        let buf2 = new Buffer(libsTxt);
        outputLibPath = hashFile(outputLibPath, buf2);
    }
    fs.writeFileSync(outputPath, jsTxt);
    console.log(`写入${outputPath}文件成功`);
    fs.writeFileSync(outputLibPath, libsTxt);
    console.log(`写入${outputLibPath}文件成功`);
    let fns = [
        'libs.js',
        outName
    ];
    if (complete !== null) {
        complete(fns);
    }
}

export function compressJs(jsList: string[], binPath: string, toPath: string, complete: Function) {
    console.log('开始压缩js文件列表');
    function compressNext() {
        if (jsList.length > 0) {
            let jsUri = jsList.shift();
            let jsLibUri = jsUri;
            let outputPath = path.join(toPath, jsUri);
            if (jsLibUri.indexOf('libs/min/') < 0) {
                jsLibUri = jsLibUri.replace('libs/', 'libs/min/');
                jsLibUri = jsLibUri.replace('.js', '.min.js');
                if (fs.existsSync(path.join(binPath, jsLibUri))) {
                    jsUri = jsLibUri;
                }
            }
            let jsPath = path.join(binPath, jsUri);
            let existJs = fs.existsSync(jsPath);
            if (!existJs) {
                console.warn('没有这个js文件, 跳过', jsUri);
                compressNext();
                return;
            }
            let jsfile = fs.readFileSync(jsPath).toString();
            // console.log('jsfile', jsfile);
            if (jsUri.indexOf('.min.js') > 0) {
                fs.writeFile(outputPath, jsfile, (err: any) => {
                    console.log('写入 outputPath', outputPath);
                    if (err) {
                        console.warn('写入压缩文件失败');
                    }
                    compressNext();
                });
            } else {
                // console.log('xxxx3222')
                let rst = uglify.minify(jsfile, {
                    mangle: true
                });
                fs.writeFile(outputPath, rst.code, (err: any) => {
                    console.log('写入 outputPath', outputPath);
                    if (err) {
                        console.warn('写入压缩文件失败');
                    }
                    compressNext();
                });
            }
        } else {
            console.log(`压缩js完成`);
            if (complete !== null) {
                complete();
            }
        }
    }
    compressNext();
}

export function getFacebookIndexHtml(jsList: string[], htmlStr: string) {
    var TEMP: string =
        '<body>\r\n\
	<script type="text/javascript" src="https://connect.facebook.net/en_US/fbinstant.6.2.js"></script>\r\n\
	<script type="text/javascript">\r\n\
		var count = 0;\r\n\
		var loadCount = 0;\r\n\
		var mainfistFiles = [\r\n\
            ${Slot}\r\n\
			];\r\n\
		window.onload = function() {\r\n\
			  count = mainfistFiles.length;\r\n\
			  FBInstant.initializeAsync().then(function(){\r\n\
				loadNext();\r\n\
			 })\r\n\
		}\r\n\
		function loadNext() {\r\n\
			var next_src = mainfistFiles.shift();\r\n\
			if (next_src) {\r\n\
				var scriptElement = document.createElement("script");\r\n\
				scriptElement.type = "text/javascript";\r\n\
				scriptElement.src = next_src;\r\n\
				document.body.appendChild(scriptElement);\r\n\
				scriptElement.onload = function () {\r\n\
					loadCount++;\r\n\
					if (window["FBInstant"]) {\r\n\
						var progress = Math.floor((loadCount / count) * 100);\r\n\
						FBInstant.setLoadingProgress(progress);\r\n\
						loadNext();\r\n\
					}\r\n\
				}\r\n\
			} \r\n\
			else {\r\n\
				fbStartGame();\r\n\
			}\r\n\
		}\r\n\
	</script>\r\n\
</body>';
    let jsStr = '';
    for (const iterator of jsList) {
        jsStr += `"${iterator}",\r\n`;
    }
    // let jsStr = jsList.join(",\r\n");
    var js_script = TEMP.replace("${Slot}", jsStr);
    let reg = new RegExp(/<body>([\s\S]*?)<\/body>/g);
    let str = htmlStr.replace(reg, js_script);
    return str;
}

const MAIN_JS_TEMP = 'BK.Script.loadlib("GameRes://${JS_URI}");';

export function cpUsedJs_handqq(jsList: string[], binPath: string, toPath: string, complete?: () => void) {
    console.log('开始拷贝js文件列表');
    let waitLayaFlag = 1; // 等待laya标记结束
    let mainJs = `
BK.Script.loadlib("GameRes://layaforqq/qqPlayCore.js");
BK.Script.loadlib("GameRes://layaforqq/bkadptpre.js");
BK.Script.loadlib("GameRes://layaforqq/domparserinone.js");`;
    for (let el of jsList) {
        let jsUri: string = el + '';
        console.log('jsUri:', jsUri);
        let jsPath = path.join(binPath, jsUri);
        let existJs = fs.existsSync(jsPath);
        if (!existJs) {
            console.warn('没有这个js文件, 跳过', jsUri);
            continue;
        }
        let targetPath = path.dirname(path.join(toPath, jsUri));
        if (!fs.existsSync(targetPath)) {
            createDirSync(targetPath, () => {
                console.log('生成dir', targetPath);
            });
        }
        fs.copyFileSync(jsPath, path.join(toPath, jsUri));
        if (jsUri.indexOf('laya.') < 0) {
            waitLayaFlag--;
        }
        if (waitLayaFlag === 0) {
            mainJs += ("\n" + `BK.Script.loadlib("GameRes://layaforqq/laya.bkadpter.js");`);
        }
        mainJs += ("\n" + MAIN_JS_TEMP.replace('${JS_URI}', jsUri));
    }
    fs.writeFileSync(path.join(toPath, 'main.js'), mainJs);
    if (complete !== null) {
        complete();
    }
}
